using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using PK3Model;


namespace sqengine.Engine.Common
{
    public class AdvancedContent : GameComponent
    {
        #region Dictionaries for textures
        private static Dictionary<string, Texture2D> _2dtextures = new Dictionary<string, Texture2D>();
        private static Dictionary<string, Model> _models = new Dictionary<string, Model>();
        private static Dictionary<string, SpriteFont> _fonts = new Dictionary<string, SpriteFont>();
        private static Dictionary<string, Effect> _effects = new Dictionary<string, Effect>();
        private static Dictionary<string, TextureCube> _texurecube = new Dictionary<string, TextureCube>();
        private static Dictionary<string, BasicEffect> _basiceffects = new Dictionary<string, BasicEffect>();
        private static Dictionary<string, CPK3Model> _pk3models = new Dictionary<string, CPK3Model>();
        private static Dictionary<string, SoundEffect> _sndeffects = new Dictionary<string, SoundEffect>();
        #endregion

        #region Variabili
        ContentManager _content;
        #endregion


        public string ContentRoot { get { return _content.RootDirectory; } }

        public class AdContentArgs : System.EventArgs
        {
            private string filename;
            private string objtype;

            public AdContentArgs(string filename, string objtype)
            {
                this.filename = filename;
                this.objtype = objtype;
            }

            public string Filename()
            {
                return filename;
            }

            public string ObjType()
            {
                return objtype;
            }
        }

        // delegate declaration
        public delegate void AdContentLoadHandler(object sender, AdContentArgs args);

        public event AdContentLoadHandler OnAdContentLoad;

        public AdvancedContent(Game game, ContentManager ContentBase)
            : base(game)
        {
            _content = ContentBase;
        }

        public override void Initialize()
        {
            base.Initialize();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                //Disposing Texture 2d
                foreach (KeyValuePair<string, Texture2D> tex in _2dtextures)
                {
                    tex.Value.Dispose();
                }


            }
            base.Dispose(disposing);
        }
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }


        #region Load functions
        public Texture2D LoadTexture2D(string name)
        {
            Texture2D texture;


            if (_2dtextures.TryGetValue(name, out texture) == true)
            {               
                return texture;
            }
            else
            {
                texture = _content.Load<Texture2D>(@name);
                _2dtextures.Add(name, texture);
                ContentLoadEvent(this, new AdContentArgs(name, texture.GetType().ToString()));
                return texture;
            }


        }

        public Model LoadModel(string name)
        {
            Model model;
            if (_models.TryGetValue(name, out model) == true)
            {
                
                return model;
            }
            else
            {
                model = _content.Load<Model>(name);
                _models.Add(name, model);
                ContentLoadEvent(this, new AdContentArgs(name, model.GetType().ToString()));
                return model;
            }
        }

        public SpriteFont LoadSpriteFont(string name)
        {
            SpriteFont spritefont;
            if (_fonts.TryGetValue(name, out spritefont) == true)
            {
              
                return spritefont;
            }
            else
            {
                spritefont = _content.Load<SpriteFont>(name);
                _fonts.Add(name, spritefont);
                ContentLoadEvent(this, new AdContentArgs(name, spritefont.GetType().ToString()));
                return spritefont;
            }
        }

        public Effect LoadEffect(string name)
        {
            Effect effect;
            if (_effects.TryGetValue(name, out effect) == true)
            {
              
                return effect;
            }
            else
            {
                effect = _content.Load<Effect>(name);
                _effects.Add(name, effect);
                ContentLoadEvent(this, new AdContentArgs(name, effect.GetType().ToString()));
                return effect;
            }
        }

        public BasicEffect LoadBasicEffect(string name)
        {
            BasicEffect basiceffect;
            if (_basiceffects.TryGetValue(name, out basiceffect) == true)
            {
               
                return basiceffect;
            }
            else
            {
                basiceffect = _content.Load<BasicEffect>(name);
                _basiceffects.Add(name, basiceffect);
                ContentLoadEvent(this, new AdContentArgs(name, basiceffect.GetType().ToString()));
                return basiceffect;
            }
        }



        public TextureCube LoadTextureCube(string name)
        {
            TextureCube texurecube;
            if (_texurecube.TryGetValue(name, out texurecube) == true)
            {
               
                return texurecube;
            }
            else
            {
                texurecube = _content.Load<TextureCube>(name);
                _texurecube.Add(name, texurecube);
                ContentLoadEvent(this, new AdContentArgs(name, texurecube.GetType().ToString()));
                return texurecube;
            }
        }


        public CPK3Model LoadPK3Model(string name)
        {
            CPK3Model pk3model;

            if (_pk3models.TryGetValue(name, out pk3model) == true)
            {
                
                return pk3model;
            }
            else
            {
                pk3model = _content.Load<CPK3Model>(name);
                _pk3models.Add(name, pk3model);
                ContentLoadEvent(this, new AdContentArgs(name, pk3model.GetType().ToString()));
                return pk3model;
            }
        }

        public SoundEffect LoadSoundEffect(string name)
        {
            SoundEffect soundeffect;
            if (_sndeffects.TryGetValue(name, out soundeffect) == true)
            {               
                return soundeffect;
            }
            else
            {
                soundeffect = _content.Load<SoundEffect>(name);
                _sndeffects.Add(name, soundeffect);
                ContentLoadEvent(this, new AdContentArgs(name, soundeffect.GetType().ToString()));
                return soundeffect;
            }
        }

        #endregion

        void ContentLoadEvent(object sender, AdContentArgs ca)
        {
            if (OnAdContentLoad != null)
                OnAdContentLoad(sender, ca);

        }

    }


}